# -*- coding: utf-8 -*-
import functools
import os
import random
import time

from selenium.common.exceptions import TimeoutException
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

from Util import logger, config
from Util.util import getPicturePath, ZTCCLOUDError, getNowTime


def explicit_wait(f):
    @functools.wraps(f)
    def wrapper(self, *loc, **kwargs):
        waitTime = config.globalPublicConf.explicitWaitTimeout
        try:
            WebDriverWait(self.driver, waitTime).until(
                EC.visibility_of_element_located(loc))
        except TimeoutException as e:
            # traceback.print_exc()
            raise ZTCCLOUDError(f"当前页面 {waitTime} 秒内未找到位置为 {loc} 的元素")
        return f(self, *loc, **kwargs)

    return wrapper


def actionWait(f):
    @functools.wraps(f)
    def wrapper(self, *args, **kwargs):
        time.sleep(config.globalPublicConf.actionStartWaitTime / 1000)
        r = f(self, *args, **kwargs)
        time.sleep(config.globalPublicConf.actionEndWaitTime / 1000)
        return r

    return wrapper


class BasePage(object):
    _isShow = config.globalPublicConf.isShow
    _toastBoxRe = (By.XPATH, '/html/body/div[3]/p')

    def __init__(self, driver):
        self.driver = driver

    @property
    def currentUrl(self):
        return self.driver.current_url

    @property
    def currentTitle(self):
        return self.driver.title

    @explicit_wait
    def find_element(self, *loc):
        return self.driver.find_element(*loc)

    @explicit_wait
    def find_elements(self, *loc):
        return self.driver.find_elements(*loc)

    def moveToElement(self, *loc):
        if len(loc) > 1:
            element = self.find_element(*loc)
        else:
            element = loc[0]
        ActionChains(self.driver).move_to_element(element).perform()
        ActionChains(self.driver).click_and_hold(element).perform()
        ActionChains(self.driver).release(element).perform()

    @actionWait
    def send_text(self, text, *loc):
        self.clear(*loc)
        try:
            self.click(*loc)
        except:
            pass
        time.sleep(random.random())
        element = self.find_element(*loc)
        self._sendKeys(element, text)

    @actionWait
    def click(self, *loc):
        element = self.find_element(*loc)
        self._clickElement(element)

    def _clickElement(self, element):
        if self._isShow:
            ActionChains(self.driver).move_to_element(element).click(element).perform()
        else:
            element.click()

    def _sendKeys(self, element, text):
        try:
            self._clickElement(element)
        except:
            pass
        ActionChains(self.driver).move_to_element(element).click(). \
            key_down(Keys.CONTROL).send_keys("a").key_up(Keys.CONTROL). \
            send_keys_to_element(element, text).perform()

    @actionWait
    def clear(self, *loc):
        element = self.find_element(*loc)
        eleLength = len(self.get_elementText(*loc))
        if self._isShow:
            if not eleLength:
                self.setAttribute(element, 'value', '')
            else:
                for _ in range(eleLength):
                    ActionChains(self.driver).send_keys_to_element(element, Keys.BACKSPACE)
        else:
            if not eleLength:
                self.setAttribute(element, 'value', '')
            else:
                element.clear()

    def get_elementText(self, *loc):
        return self.find_element(*loc).text.strip(" ")

    @actionWait
    def refresh(self):
        self.driver.refresh()
        logger.info("页面刷新")

    def screenshot(self, code, imgName):
        imgName = f"{imgName}_{getNowTime().replace(':', '：')}"
        baseImgPath = getPicturePath(code, imgName)
        self.driver.get_screenshot_as_file(baseImgPath)
        imgPath = baseImgPath.replace(os.sep, "/").split(config.rootPath.replace(os.sep, "/"))[1]
        _imgPath = imgPath.split("/")
        imgDir = "/".join(_imgPath[:-1])
        imgName = _imgPath[-1].split(".")[0]
        logger.info(f"截图成功，目录：{imgDir}，名称：{imgName}")
        return baseImgPath

    def elementExistsIsOrNot(self, *loc) -> bool:
        try:
            self.driver.find_element(*loc)
        except Exception:
            logger.info("元素不存在")
            return False
        else:
            logger.info("元素存在")
            return True

    def elementIsEnable(self, *loc) -> bool:
        return self.driver.find_element(*loc).is_enabled()

    def elementIsDisplay(self, *loc) -> bool:
        return self.driver.find_element(*loc).is_displayed()

    def elementIsSelect(self, *loc) -> bool:
        return self.driver.find_element(*loc).is_selected()

    def getElementAttribute(self, attribute, *loc):
        return self.driver.find_element(*loc).get_attribute(attribute)

    _toastBox = (By.CLASS_NAME, 'el-message-box__content')

    def getToastBoxText(self):
        elements = self.find_elements(*self._toastBox)
        content = elements[-1].text
        return content

    _boxMessage = (By.CLASS_NAME, 'el-message-box')

    def getBoxMessage(self):
        content = self.find_element(*self._boxMessage).text
        return content

    _boxMessage2 = (By.CLASS_NAME, 'el-message__content')

    def getBoxMessage2(self):
        content = self.find_element(*self._boxMessage2).text
        return content

    _fuShenMessage = (By.XPATH, '//p[@class="text"]')

    def getFuShenMessage(self):
        content = self.find_element(*self._fuShenMessage).text
        return content

    def getWindowHandles(self):
        return self.driver.window_handles

    def getCurrentWindowHandle(self):
        return self.driver.current_window_handle

    # ---------- 切换操作 ----------

    def switchToWindow(self, window):
        self.driver.switch_to.window(window)

    # 切换到当前窗口，并关闭所有后续窗口
    def switchToCurrentWindow(self):
        currentHandle = self.getCurrentWindowHandle()
        for handle in self.getWindowHandles()[::-1]:
            if handle != currentHandle:
                self.switchToWindow(handle)
                self.driver.close()
            else:
                self.switchToWindow(handle)
                break

    def switchToFrame(self, iframe: tuple or str):
        if not isinstance(iframe, str):
            self.driver.switch_to.frame(self.driver.find_element(*iframe))
        else:
            self.driver.switch_to.frame(iframe)

    def switchToParentFrame(self):
        self.driver.switch_to.frame()

    def back(self):
        self.driver.back()
        logger.info("浏览器回退操作")

    # 执行JS代码
    def executeScript(self, js, *args):
        # 'window.scrollTo(0,document.body.scrollHeight)'
        self.driver.execute_script(js, *args)

    @property
    def _documentHeight(self):
        return self.driver.execute_script("return document.documentElement.scrollHeight")

    @property
    def _documentWidth(self):
        return self.driver.execute_script("return document.documentElement.scrollWidth")

    def _elementWidth(self, element):
        return self.driver.execute_script("return arguments[0].scrollWidth", element)

    def _elementHeight(self, element):
        return self.driver.execute_script("return arguments[0].scrollHeight", element)

    def scrollToTop(self, element=None):
        if element:
            js = f'arguments[0].scrollTop=0'
            self.executeScript(js, element)
        else:
            js = "document.documentElement.scrollTop=0"
            self.executeScript(js)

    def scrollToBottom(self, element=None):
        if element:
            js = f'arguments[0].scrollTop=arguments[1]'
            self.executeScript(js, element, self._elementHeight(element))
        else:
            js = f"document.documentElement.scrollTop={self._documentHeight}"
            self.executeScript(js)

    def scrollToLeft(self, element=None):
        if element:
            js = f'arguments[0].scrollLeft=0'
            self.executeScript(js, element)
        else:
            js = f"document.documentElement.scrollTLeft=0"
            self.executeScript(js)

    def scrollToRight(self, element=None):
        if element:
            js = f'arguments[0].scrollLeft=arguments[1]'
            self.executeScript(js, element, self._elementWidth(element))
        else:
            js = f"document.documentElement.scrollTLeft={self._documentWidth}"
            self.executeScript(js)

    def scrollIntoView(self, target):
        js = 'arguments[0].scrollIntoView()'
        self.executeScript(js, target)

    def setAttribute(self, element, attrName, attrValue):
        js = f'arguments[0].setAttribute(arguments[1],arguments[2])'
        self.executeScript(js, element, attrName, attrValue)

    def scrollToSpecifyPercentPosition(self, heightPercent: float = 0.0, widthPercent: float = 0.0, element=None):
        """
            页面滚动到指定位置
        :param element: h5页面元素对象
        :param heightPercent: 高度比例，例如：0.8(占总比例的80%)
        :param widthPercent: 宽度比例
        :return:
        """
        if element:
            height = self._elementHeight(element) * heightPercent
            width = self._elementWidth(element) * widthPercent
            js = f"arguments[0].scrollTo({width},{height})"
            self.executeScript(js, element)
        else:
            height = self._documentHeight * heightPercent
            width = self._documentWidth * widthPercent
            js = f"window.scrollTo({width}, {height})"
            self.executeScript(js)

    # 切换到最后一个非当前handle窗口
    def switchWindow(self):
        currentWindow = self.getCurrentWindowHandle()
        num = 0
        while True:
            if self.getWindowHandles()[-1] != currentWindow:
                break
            num += 1
            if num == 1000:
                break
        windowsList = self.getWindowHandles()
        windowsListLength = len(windowsList)
        logger.debug(f"所有窗口为：{windowsList}")
        index = 0
        for i in range(windowsListLength - 1, -1, -1):
            if windowsListLength == 1:
                break
            if currentWindow != windowsList[i]:
                index = i
                break
        self.switchToWindow(windowsList[index])
        logger.debug(f"当前窗口句柄号为：{self.getCurrentWindowHandle()}，标题为：{self.currentTitle}，url为：{self.currentUrl}")

    # 关闭当前窗口and切换回上一个窗口
    def closeCurrentWindows(self):
        self.driver.close()
        self.switchWindow()

    # 复制当前标签页，并切换
    def copyCurrentPageToAnotherPage(self):
        js = f"window.open('{self.currentUrl}')"
        self.executeScript(js)
        windowsList = self.getWindowHandles()
        self.switchToWindow(windowsList[-1])
        logger.info('复制当前标签页，并跳转到新复制的页签')

    # ------ 操作通用控件 ------

    @actionWait
    def click_button(self, buttonName):
        self.click_by_name(buttonName, tagName='button')

    @actionWait
    def click_by_name(self, textName, index=0, tagName="*") -> None:
        """
        说明：
            通过名字点击按钮（全页面）
        :param textName:    名字
        :param index:    索引
        :param tagName:    标签名，默认全部标签
        :return: None
        """
        elementList = self.find_elements(*(By.TAG_NAME, tagName))
        textElementList = [element for element in elementList if element.text.strip(" ") == textName]
        if index >= len(elementList):
            raise ZTCCLOUDError(f"index out of range")
        if self._isShow:
            ActionChains(self.driver).move_to_element(textElementList[index]).click(textElementList[index]).perform()
        else:
            textElementList[index].click()

    @actionWait
    def select_item(self, content) -> None:
        """
        说明：
            浮动下拉框选择
        :param content:    选择内容
        :return: None
        """
        isPerform = config.globalPublicConf.isShow
        elementList = self.find_elements(*(By.XPATH, '//*[contains(@class, "el-select-dropdown__item")]'))
        for ele in elementList:
            if ele.text == content:
                if isPerform:
                    ActionChains(self.driver).move_to_element(ele).click(on_element=ele).perform()
                else:
                    ele.click()
                break

    @actionWait
    def input_amount(self, text, *loc) -> None:
        """
        说明：
            金额输入框输入
        :param text:    金额
        :param *loc:    定位元素
        :return: None
        """
        self.click(*loc)
        self.clear(*loc)
        element = self.find_element(*loc)
        self._sendKeys(element, text)

    @actionWait
    def select_option(self, option, *loc) -> None:
        """
        说明：
            系统编码下拉选择框选择
        :param option:  下拉框选择项
        :param loc:    定位元素
        :return: None
        """
        self.click(*loc)
        time.sleep(random.random())
        i = 0
        try:
            while True:
                if self.get_elementText(*(loc[0], (loc[1] + f'.option.{i}'))) == option:
                    self.click(*(loc[0], (loc[1] + f'.option.{i}')))
                    break
                i += 1
        except ZTCCLOUDError:
            raise ZTCCLOUDError('没有找到对应配置项，请检查配置')
        logger.info('选择的数据为：{}'.format(option))

    _calendar = (By.CLASS_NAME, 'calendar')

    @actionWait
    def select_date(self, year, month, day) -> None:
        """
        说明：
            日期控件选择 年 月 日
        :param year:    年
        :param month:   月
        :param day:     日
        :return: None
        """

        year = str(int(year))
        month = str(int(month))
        day = str(int(day))

        time.sleep(random.random())
        # WebDriverWait(self.driver, 5).until(
        #     EC.visibility_of_element_located( (By.CLASS_NAME, 'el-date-picker__header') ))
        if len(self.find_elements(*(By.CLASS_NAME, 'el-picker-panel__body'))) > 1:
            index = len(self.find_elements(*(By.CLASS_NAME, 'el-picker-panel__body'))) - 1
            dateHeaderPanel = self.find_elements(*(By.CLASS_NAME, 'el-date-picker__header'))[index]
            dateContentPanel = self.find_elements(*(By.CLASS_NAME, 'el-picker-panel__content'))[index]
        else:
            dateHeaderPanel = self.find_element(*(By.CLASS_NAME, 'el-date-picker__header'))
            dateContentPanel = self.find_element(*(By.CLASS_NAME, 'el-picker-panel__content'))

        # 操作年份
        selectedY = dateHeaderPanel.find_elements(*(By.TAG_NAME, 'span'))[0].text
        selectedYear = selectedY.split(' ')[0]
        if year > selectedYear:
            num = int(year) - int(selectedYear)
            for i in range(num):
                dateHeaderPanel.find_elements(*(By.TAG_NAME, 'button'))[2].click()
        elif year < selectedYear:
            num = int(selectedYear) - int(year)
            for i in range(num):
                dateHeaderPanel.find_elements(*(By.TAG_NAME, 'button'))[0].click()
        elif year == selectedYear:
            pass

        # 操作月份
        selectedM = dateHeaderPanel.find_elements(*(By.TAG_NAME, 'span'))[1].text
        selectedMonth = selectedM.split(' ')[0]
        if month > selectedMonth:
            num = int(month) - int(selectedMonth)
            for i in range(num):
                dateHeaderPanel.find_elements(*(By.TAG_NAME, 'button'))[3].click()
        elif month < selectedMonth:
            num = int(selectedMonth) - int(month)
            for i in range(num):
                dateHeaderPanel.find_elements(*(By.TAG_NAME, 'button'))[1].click()
        elif month == selectedMonth:
            pass

        # 操作日
        dayTable = dateContentPanel.find_element(*(By.CLASS_NAME, 'el-date-table'))
        startNum = 0
        for i in range(len(dayTable.find_elements(*(By.TAG_NAME, 'span')))):
            if dayTable.find_elements(*(By.TAG_NAME, 'span'))[i].text == '1':
                startNum = i
                break
        for i in range(startNum, len(dayTable.find_elements(*(By.TAG_NAME, 'span')))):
            if dayTable.find_elements(*(By.TAG_NAME, 'span'))[i].text == day:
                dayTable.find_elements(*(By.TAG_NAME, 'span'))[i].click()
                break
        try:
            ele = self.driver.find_element(*(By.XPATH, '//div[contains(@class, "el-picker-panel")]'
                                                '/div[@class="el-picker-panel__footer"]'))
        except ZTCCLOUDError:
            pass
        else:
            if 'display: none' not in ele.get_attribute('style'):
                ele.find_elements(*(By.TAG_NAME, 'button'))[1].click()

    @actionWait
    def clickTargetButton(self, buttonType) -> None:
        """
        说明：
            根据 buttonType 选择不同类型的按钮进行点击(页签栏)
        :param buttonType: 按钮名字
        :return: None
        """
        elButtonElementList = self.find_elements(*(By.CLASS_NAME, 'el-button'))
        flag = False
        for element in elButtonElementList:
            if element.text == buttonType:
                self._clickElement(element)
                logger.info(f'点击 {buttonType} 按钮')
                flag = True
                break
        if not flag:
            raise ZTCCLOUDError(f"当前页面未找到名称为 {buttonType} 的按钮")

    def waitLoading(self):
        s = time.time()
        while 1:
            try:
                WebDriverWait(self.driver, random.random()).until(
                    EC.visibility_of_element_located((By.XPATH, 'div[@class="el-loading-spinner"]')))
            except Exception as e:
                return True
            else:
                if time.time() - s > 30:
                    return False
                time.sleep(random.random())

    # 迷你弹窗选择器
    @actionWait
    def selectValueFromMiniTable(self, **kwargs) -> None:
        """
            迷你弹窗选择器
            如果未传入任何参数，则默认选择第一条；
            否则根据传入的参数进行选择
        :param kwargs: label与value对应字典，例如：{'编码': '123456', '名称': '测试名称'}
        :return: None
        """
        self.__selectValueFromTable(tableType='mini', **kwargs)

    # 小弹窗选择器
    @actionWait
    def selectValueFromSmallTable(self, **kwargs):
        """
            小弹窗选择器
            如果未传入任何参数，则默认选择第一条；
            否则根据传入的参数进行选择
        :param kwargs: label与value对应字典，例如：{'编码': '123456', '名称': '测试名称'}
        :return: None
        """
        self.__selectValueFromTable(tableType='small', **kwargs)

    def __selectValueFromTable(self, tableType, **kwargs) -> None:
        """
            弹窗选择器(mini or small)
        :param tableType: 选择框类型：small or mini
        :param kwargs: label与value对应字典，例如：{'编码': '123456', '名称': '测试名称'}
        :return: None
        """
        if not self.waitLoading():
            raise ZTCCLOUDError('超过30秒未查询出数据，请确认')
        indexList = []
        labelNameList = list(kwargs.keys())
        valueList = list(kwargs.values())
        baseXpath = f'//div[@class="el-dialog__wrapper table-picker"]//div[@class="zte-table zte-table--{tableType}"]'
        if (not labelNameList) and (not valueList):
            emptyXpath = baseXpath + '/div[@class="table-body"]//table[contains(@class, "el-table__body")]//tr'
            tr_ele = self.find_element(*(By.XPATH, emptyXpath))
            ActionChains(self.driver).double_click(tr_ele).perform()
            self.switchToCurrentWindow()
            return
        searchLabelXpath = baseXpath + '/div[@class="search-body"]//label'
        # 根据传入的label和value查找并填写对应的查询条件，点击查询按钮
        labelElementList = self.find_elements(*(By.XPATH, searchLabelXpath))
        bodyHeaderXpath = baseXpath + '//table[@class="el-table__header"]//tr//th'
        elementList = self.find_elements(*(By.XPATH, bodyHeaderXpath))
        headerIndexList = []
        for labelName in labelNameList:
            flag = False
            for idx, labelElement in enumerate(labelElementList):
                if labelElement.text == labelName:
                    indexList.append(idx)
                    flag = True
                    break
            if not flag:
                raise ZTCCLOUDError(f"未找到label为 {labelName} 的标签")
            # 找body中对应的字段位置
            flag = False
            for idx, element in enumerate(elementList):
                if element.text == labelName:
                    headerIndexList.append(idx)
                    flag = True
                    break
            if not flag:
                raise ZTCCLOUDError(f"bodyHeader中没有找到{labelName}对应字段，请检查")
        searchValueXpath = baseXpath + '/div[@class="search-body"]//input'
        valueElementList = self.find_elements(*(By.XPATH, searchValueXpath))
        for idx, index in enumerate(indexList):
            self._sendKeys(valueElementList[index], valueList[idx])
        searchButton = baseXpath + '/div[@class="search-body"]//button'
        self.click(*(By.XPATH, searchButton))

        tr_bodyXpath = baseXpath + '/div[@class="table-body"]//table[@class="el-table__body"]//tr'
        tr_elementList = self.find_elements(*(By.XPATH, tr_bodyXpath))
        td_elementXpath = './/td'
        headerIndexLength = len(headerIndexList)
        n = 0
        gFlag = False
        for idx, index in enumerate(headerIndexList):
            flag = False
            tr_element = ""
            for tr_element in tr_elementList:
                td_elementList = tr_element.find_elements(*(By.XPATH, td_elementXpath))
                if not td_elementList:
                    raise ZTCCLOUDError("无任何数据，请检查配置")
                for _ in range(headerIndexLength):
                    if td_elementList[index].text == valueList[idx]:
                        n += 1
                    if n == headerIndexLength:
                        flag = True
                        break
            if flag:
                ActionChains(self.driver).double_click(tr_element).perform()
                gFlag = True
                break
        if not gFlag:
            raise ZTCCLOUDError("没有找到对应数据，请确认")
        self.switchToCurrentWindow()

    # 大弹窗选择器
    @actionWait
    def selectValueFromMultiTable(self, *args) -> None:
        """
            大弹窗选择器
            如果未传入任何参数，则默认选择第一条；
            否则根据传入的参数进行选择(多选)
        :param args: label与value对应字典，例如：[{'编码': '123456', '名称': '测试名称'}, {'编码': '956', '名称': '测试2'}]
        :return: None
        """
        if not self.waitLoading():
            raise ZTCCLOUDError('超过30秒未查询出数据，请确认')
        baseXpath = '//div[contains(@class, "muti-select-table")]'
        if not args:
            emptyXpath = baseXpath + '/div[@class="table-container"]' \
                                     '/div[@class="table-body"]' \
                                     '//div[contains(@class, "el-table__body-wrapper")]//tr'
            tr_ele = self.find_element(*(By.XPATH, emptyXpath))
            self._clickElement(tr_ele)
            self.click_button('提交')
            self.switchToCurrentWindow()
            return
        searchBaseXpath = baseXpath + '/div[@class="search-body"]'
        searchLabelXpath = searchBaseXpath + '//label'
        # 根据传入的label和value查找并填写对应的查询条件，点击查询按钮
        labelElementList = self.find_elements(*(By.XPATH, searchLabelXpath))
        bodyHeaderXpath = baseXpath + '//div[@class="table-body"]' \
                                      '//div[@class="el-table__header-wrapper"]' \
                                      '/table/thead/tr/th'
        elementList = self.find_elements(*(By.XPATH, bodyHeaderXpath))

        labelNameListList = []
        valueListList = []
        for i in args:
            a = []
            b = []
            for j, k in i.items():
                a.append(j)
                b.append(k)
            labelNameListList.append(a)
            valueListList.append(b)
        headerIndexListList = []
        indexListList = []
        for labelNameList in labelNameListList:
            headerIndexList = []
            indexList = []
            for labelName in labelNameList:

                flag = False
                for idx, labelElement in enumerate(labelElementList):
                    if labelElement.text == labelName:
                        indexList.append(idx)
                        flag = True
                        break
                if not flag:
                    raise ZTCCLOUDError(f"未找到label为 {labelName} 的标签")

                # 找body中对应的字段位置
                flag = False
                for idx, element in enumerate(elementList):
                    if element.text == labelName:
                        headerIndexList.append(idx)
                        flag = True
                        break
                if not flag:
                    raise ZTCCLOUDError(f"bodyHeader中没有找到{labelName}对应字段，请检查")
            indexListList.append(indexList)
            headerIndexListList.append(headerIndexList)
        searchValueXpath = baseXpath + '/div[@class="search-body"]//input'
        valueElementList = self.find_elements(*(By.XPATH, searchValueXpath))
        for idxx, indexList in enumerate(indexListList):
            for idx, index in enumerate(indexList):
                self._sendKeys(valueElementList[index], valueListList[idxx][idx])
            searchButton = searchBaseXpath + '//button'
            self.click(*(By.XPATH, searchButton))

            tr_bodyXpath = baseXpath + '//div[@class="table-body"]//table[@class="el-table__body"]//tr'
            tr_elementList = self.find_elements(*(By.XPATH, tr_bodyXpath))
            td_elementXpath = './/td'
            headerIndexLength = len(headerIndexListList[idxx])
            n = 0
            gFlag = False
            for idx, index in enumerate(headerIndexListList[idxx]):
                flag = False
                tr_element = ""
                for tr_element in tr_elementList:
                    td_elementList = tr_element.find_elements(*(By.XPATH, td_elementXpath))
                    if not td_elementList:
                        raise ZTCCLOUDError("无任何数据，请检查配置")
                    for _ in range(headerIndexLength):
                        if td_elementList[index].text == valueListList[idxx][idx]:
                            n += 1
                        if n == headerIndexLength:
                            flag = True
                            break
                if flag:
                    self._clickElement(tr_element)
                    self.switchToCurrentWindow()
                    gFlag = True
                    break
            if not gFlag:
                raise ZTCCLOUDError("没有找到对应数据，请确认")
        submitButton = (By.XPATH, baseXpath + '/../../div[@class="el-dialog__footer"]//button[2]')
        self.click(*submitButton)

    @actionWait
    def copyCurrentWindow(self, count=1):
        js = f'window.open("{self.driver.current_url}")'
        for _ in range(count):
            self.executeScript(js)
        self.switchWindow()

    @actionWait
    def lovSelectTable(self, content, *loc, num=1, tip='div'):
        """
        lov弹出框选择器
        如界面存在多个下拉选择框，且选项一致，lov弹出框所选内容不能重复。后续优化
        """
        if num > 3:
            logger.error(f"lov下拉框3次均未选择到内容为 {content} 的选项")
            raise AssertionError(f"lov下拉框未选择到内容为 {content} 的选项")
        try:
            self.click(*loc)
            self.send_text(content, *loc)
            # 选筛选后的第一个
            time.sleep(2)
            self.click(*(By.XPATH, f'//{tip}[text()="{content}"]'))
        except Exception as e:
            return self.lovSelectTable(content, *loc, num=num + 1)
